package com.bdbit.ChargingStation.services;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.slf4j.Logger;
import javax.annotation.PostConstruct;
import java.util.List;
import org.springframework.scheduling.annotation.Scheduled;
import org.slf4j.LoggerFactory;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Service
public class DeviceOrderService {
    private static final Logger log = LoggerFactory.getLogger(DeviceOrderService.class);
    
    // 充电桩编码与订单的关联映射
    private final Map<String, String> deviceOrderMap = new ConcurrentHashMap<>();
    
    @Autowired
    private ChargingOrderService chargingOrderService;
    
    // 文件: DeviceOrderService.java
    public void bindDevice(String eleCode, String orderId) {
        bindDeviceToOrder(eleCode, orderId);
    }
    
    /**
     * 绑定充电桩与订单
     * @param eleCode 充电桩编码
     * @param orderId 订单ID
     */
    public void bindDeviceToOrder(String eleCode, String orderId) {
        deviceOrderMap.put(eleCode, orderId);
        log.info("充电桩绑定成功: eleCode={}, orderId={}", eleCode, orderId);
    }

    /**
     * 解绑充电桩与订单
     * @param eleCode 充电桩编码
     */
    public void unbindDevice(String eleCode) {
        String orderId = deviceOrderMap.remove(eleCode);
        if (orderId != null) {
            log.info("充电桩解绑成功: eleCode={}, orderId={}", eleCode, orderId);
        }
    }
    
    /**
     * 根据充电桩编码获取订单ID（仅从内存查询）
     * @param eleCode 充电桩编码
     * @return 订单ID，如果没有找到则返回null
     */
    public String getOrderIdByDevice(String eleCode) {
        return deviceOrderMap.get(eleCode);
    }

    /**
     * 统一查询充电桩关联的订单ID（内存+数据库双重查询）
     * @param eleCode 充电桩编码
     * @return 订单ID，如果没有找到则返回null
     */
    public String getOrderIdByDeviceUnified(String eleCode) {
        String orderId = null;

        // 如果内存中没有，从数据库查询
        try {
            orderId = chargingOrderService.getOrderIdByDevice(eleCode);
        } catch (Exception e) {
            log.error("从数据库查询充电桩订单关系失败: eleCode={}", eleCode, e);
        }

        return orderId;
    }

    /**
     * 根据订单获取充电桩编码
     * @param orderId 订单ID
     * @return 充电桩编码
     */
    public String getDeviceIdByOrder(String orderId) {
        return deviceOrderMap.entrySet().stream()
            .filter(entry -> entry.getValue().equals(orderId))
            .map(Map.Entry::getKey)
            .findFirst()
            .orElse(null);
    }

    /**
     * 应用启动时恢复充电桩-订单映射关系
     */
    @PostConstruct
    public void recoverDeviceOrderMappings() {
        try {
            log.info("开始恢复充电桩-订单映射关系...");
            
            // 从数据库查询所有活跃订单（充电中、已支付等状态）
            List<String> activeEleCodes = chargingOrderService.getActiveDeviceIds();
            
            int recoveredCount = 0;
            for (String eleCode : activeEleCodes) {
                String orderId = chargingOrderService.getOrderIdByDevice(eleCode);
                if (orderId != null) {
                    deviceOrderMap.put(eleCode, orderId);
                    recoveredCount++;
                }
            }
            
            log.info("充电桩-订单映射关系恢复完成，共恢复{}个映射", recoveredCount);
        } catch (Exception e) {
            log.error("恢复充电桩-订单映射关系失败", e);
        }
    }

    /**
     * 定期同步充电桩-订单映射关系
     */
    @Scheduled(fixedRate = 300000) // 每5分钟执行一次
    public void syncDeviceOrderMappings() {
        try {
            log.debug("开始定期同步充电桩-订单映射关系...");
            
            List<String> activeEleCodes = chargingOrderService.getActiveDeviceIds();
            
            // 清理已完成订单的映射
            deviceOrderMap.entrySet().removeIf(entry -> {
                String eleCode = entry.getKey();
                return !activeEleCodes.contains(eleCode);
            });
            
            // 添加新的映射
            for (String eleCode : activeEleCodes) {
                if (!deviceOrderMap.containsKey(eleCode)) {
                    String orderId = chargingOrderService.getOrderIdByDevice(eleCode);
                    if (orderId != null) {
                        deviceOrderMap.put(eleCode, orderId);
                        log.info("同步新的充电桩映射: eleCode={}, orderId={}", eleCode, orderId);
                    }
                }
            }
            
            log.debug("充电桩-订单映射关系同步完成，当前映射数量：{}", deviceOrderMap.size());
        } catch (Exception e) {
            log.error("同步充电桩-订单映射关系失败", e);
        }
    }
}